"""
Bookings router for managing meeting room bookings.
"""
from typing import List, Optional, Annotated
from fastapi import APIRouter, Depends, Query
from sqlalchemy.orm import Session
from datetime import datetime
from uuid import UUID
from app.database import get_db
from app.schemas.booking import (
    BookingCreate,
    BookingUpdate,
    BookingResponse,
    CheckAvailabilityRequest,
    CheckAvailabilityResponse
)
from app.services import booking_service
from app.routers.auth import get_current_user
from app.models.user import User
from app.models.booking import BookingStatus

router = APIRouter()


@router.post("/", response_model=BookingResponse, status_code=201)
def create_booking(
    booking: BookingCreate,
    db: Session = Depends(get_db)
):
    """
    Create a new booking.
    Validates time slot availability and room schedule.
    Public endpoint - no authentication required for guest bookings.
    """
    db_booking = booking_service.create_booking(db, booking)
    return BookingResponse.from_orm(db_booking)


@router.get("/", response_model=List[BookingResponse])
def get_bookings(
    skip: int = Query(0, ge=0),
    limit: int = Query(100, ge=1, le=1000),
    room_id: Optional[UUID] = None,
    date: Optional[datetime] = None,
    booking_person: Optional[str] = None,
    status: Optional[BookingStatus] = None,
    db: Session = Depends(get_db)
):
    """
    Get all bookings with optional filters.
    Public endpoint - no authentication required.
    
    Query Parameters:
    - skip: Number of records to skip (pagination)
    - limit: Maximum number of records to return
    - room_id: Filter by room ID
    - date: Filter by booking date
    - booking_person: Filter by booking person name (partial match)
    - status: Filter by booking status
    """
    bookings = booking_service.get_bookings(
        db, skip=skip, limit=limit,
        room_id=room_id, date=date, booking_person=booking_person, status=status
    )
    return [BookingResponse.from_orm(booking) for booking in bookings]


@router.get("/{booking_id}", response_model=BookingResponse)
def get_booking(
    booking_id: UUID,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """
    Get a specific booking by ID.
    """
    from fastapi import HTTPException, status
    
    booking = booking_service.get_booking(db, booking_id)
    if not booking:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Booking not found"
        )
    return BookingResponse.from_orm(booking)


@router.put("/{booking_id}", response_model=BookingResponse)
def update_booking(
    booking_id: UUID,
    booking_update: BookingUpdate,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """
    Update an existing booking.
    Validates new time slot if time is being updated.
    """
    updated_booking = booking_service.update_booking(db, booking_id, booking_update)
    return BookingResponse.from_orm(updated_booking)


@router.delete("/{booking_id}")
def delete_booking(
    booking_id: UUID,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """
    Cancel a booking (soft delete).
    Requires authentication; non-admin users can only cancel their own bookings.
    """
    booking_service.delete_booking(db, booking_id, current_user)
    return {"message": "Booking cancelled successfully"}


@router.post("/check-availability", response_model=CheckAvailabilityResponse)
def check_availability(
    request: CheckAvailabilityRequest,
    db: Session = Depends(get_db)
):
    """
    Check if a room is available for a specific time slot.
    Public endpoint - no authentication required.
    Returns availability status and any conflicting bookings.
    """
    return booking_service.check_availability(
        db,
        request.room_id,
        request.start_time,
        request.end_time,
        request.exclude_booking_id
    )